Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 24da5de7fd3e7b4204880f3095c25e95a9bfc545


Parents : 96ad7a3
Author : Ivan <ivan@quad4.io>
Signature : Signature validation error
Date : 2026-04-30T11:46:23-05:00

feat(interface): update AddInterfacePage with dynamic interface selection and localization updates for multiple languages

Changes
Diff

diff --git a/meshchatx/src/frontend/components/interfaces/AddInterfacePage.vue b/meshchatx/src/frontend/components/interfaces/AddInterfacePage.vue
index 17df717e..8480cd30 100644
--- a/meshchatx/src/frontend/components/interfaces/AddInterfacePage.vue
+++ b/meshchatx/src/frontend/components/interfaces/AddInterfacePage.vue
@@ -1117,6 +1117,48 @@
placeholder="e.g. eth0, wlan0"
class="input-field"
/>
+ <div
+ v-if="
+ hostKernelInterfacesLoading ||
+ hostKernelInterfaces.length ||
+ hostKernelInterfacesUnavailable
+ "
+ class="mt-1.5 space-y-1"
+ >
+ <p class="text-[10px] text-gray-500 dark:text-zinc-500">
+ {{ $t("interfaces.auto_iface_ifname_chips_hint") }}
+ </p>
+ <div
+ v-if="hostKernelInterfacesLoading"
+ class="text-[10px] text-gray-400"
+ >
+ {{ $t("interfaces.kernel_iface_loading") }}
+ </div>
+ <div v-else class="flex flex-wrap gap-1 max-h-20 overflow-y-auto">
+ <button
+ v-for="iface in hostKernelInterfaces"
+ :key="'auto-allow-' + iface.name"
+ type="button"
+ class="max-w-full truncate px-1.5 py-0.5 text-[10px] rounded border font-mono transition-colors"
+ :class="
+ autoInterfaceChipActive(
+ 'newInterfaceDevices',
+ iface.name
+ )
+ ? 'border-blue-400 bg-blue-50/90 text-blue-900 dark:border-blue-500 dark:bg-blue-950/40 dark:text-blue-200'
+ : 'border-gray-200 bg-white/80 text-gray-800 hover:border-blue-300 dark:border-zinc-700 dark:bg-zinc-900/80 dark:text-zinc-200 dark:hover:border-blue-500'
+ "
+ @click="
+ toggleAutoInterfaceCommaToken(
+ 'newInterfaceDevices',
+ iface.name
+ )
+ "
+ >
+ {{ iface.name }}
+ </button>
+ </div>
+ </div>
</div>
<div>
<FormLabel class="glass-label"
@@ -1128,6 +1170,48 @@
placeholder="e.g. tun0, docker0"
class="input-field"
/>
+ <div
+ v-if="
+ hostKernelInterfacesLoading ||
+ hostKernelInterfaces.length ||
+ hostKernelInterfacesUnavailable
+ "
+ class="mt-1.5 space-y-1"
+ >
+ <p class="text-[10px] text-gray-500 dark:text-zinc-500">
+ {{ $t("interfaces.auto_iface_ifname_chips_hint") }}
+ </p>
+ <div
+ v-if="hostKernelInterfacesLoading"
+ class="text-[10px] text-gray-400"
+ >
+ {{ $t("interfaces.kernel_iface_loading") }}
+ </div>
+ <div v-else class="flex flex-wrap gap-1 max-h-20 overflow-y-auto">
+ <button
+ v-for="iface in hostKernelInterfaces"
+ :key="'auto-ignore-' + iface.name"
+ type="button"
+ class="max-w-full truncate px-1.5 py-0.5 text-[10px] rounded border font-mono transition-colors"
+ :class="
+ autoInterfaceChipActive(
+ 'newInterfaceIgnoredDevices',
+ iface.name
+ )
+ ? 'border-amber-400 bg-amber-50/90 text-amber-950 dark:border-amber-600 dark:bg-amber-950/40 dark:text-amber-100'
+ : 'border-gray-200 bg-white/80 text-gray-800 hover:border-amber-300 dark:border-zinc-700 dark:bg-zinc-900/80 dark:text-zinc-200 dark:hover:border-amber-600'
+ "
+ @click="
+ toggleAutoInterfaceCommaToken(
+ 'newInterfaceIgnoredDevices',
+ iface.name
+ )
+ "
+ >
+ {{ iface.name }}
+ </button>
+ </div>
+ </div>
</div>
<div>
<FormLabel class="glass-label">Configured Bitrate (bps)</FormLabel>
@@ -2118,6 +2202,32 @@ export default {
}
return rest;
},
+ autoInterfaceChipActive(fieldKey, token) {
+ const raw = this[fieldKey];
+ if (raw == null || raw === "") {
+ return false;
+ }
+ return String(raw)
+ .split(",")
+ .map((s) => s.trim())
+ .includes(token);
+ },
+ toggleAutoInterfaceCommaToken(fieldKey, token) {
+ const raw = this[fieldKey];
+ let str = raw == null || raw === "" ? "" : String(raw);
+ const tokens = str
+ .split(",")
+ .map((s) => s.trim())
+ .filter(Boolean);
+ const i = tokens.indexOf(token);
+ if (i === -1) {
+ tokens.push(token);
+ } else {
+ tokens.splice(i, 1);
+ }
+ const next = tokens.join(", ");
+ this[fieldKey] = next === "" ? null : next;
+ },
async loadHostKernelInterfaces() {
this.hostKernelInterfacesLoading = true;
this.hostKernelInterfacesUnavailable = null;

diff --git a/meshchatx/src/frontend/locales/de.json b/meshchatx/src/frontend/locales/de.json
index 040cee66..a173cb89 100644
--- a/meshchatx/src/frontend/locales/de.json
+++ b/meshchatx/src/frontend/locales/de.json
@@ -960,7 +960,8 @@
"listen_ip_required": "Listen-IP ist erforderlich.",
"kernel_iface_picker_title": "Schnittstellen auf diesem Rechner",
"kernel_iface_loading": "Laden…",
- "kernel_iface_picker_help": "Optional ein Kernel-Interface-Name, oder leer lassen und nur über Listen-IP binden. Klick füllt das Feld."
+ "kernel_iface_picker_help": "Optional ein Kernel-Interface-Name, oder leer lassen und nur über Listen-IP binden. Klick füllt das Feld.",
+ "auto_iface_ifname_chips_hint": "Schnittstellen dieses Rechners: Klicken zum Hinzufügen oder Entfernen im Feld darüber."
},
"map": {
"title": "Karte",

diff --git a/meshchatx/src/frontend/locales/en.json b/meshchatx/src/frontend/locales/en.json
index 39d8b5f1..203ed56f 100644
--- a/meshchatx/src/frontend/locales/en.json
+++ b/meshchatx/src/frontend/locales/en.json
@@ -908,7 +908,8 @@
"listen_ip_required": "Listen IP is required.",
"kernel_iface_picker_title": "Interfaces on this host",
"kernel_iface_loading": "Loading…",
- "kernel_iface_picker_help": "Device is optional: one kernel interface name, or leave empty to bind using Listen IP only. Click a row to fill the field."
+ "kernel_iface_picker_help": "Device is optional: one kernel interface name, or leave empty to bind using Listen IP only. Click a row to fill the field.",
+ "auto_iface_ifname_chips_hint": "This host's interfaces: click to add or remove names in the field above."
},
"map": {
"title": "Map",

diff --git a/meshchatx/src/frontend/locales/es.json b/meshchatx/src/frontend/locales/es.json
index a4ec0db3..84778f10 100644
--- a/meshchatx/src/frontend/locales/es.json
+++ b/meshchatx/src/frontend/locales/es.json
@@ -908,7 +908,8 @@
"listen_ip_required": "La IP de escucha es obligatoria.",
"kernel_iface_picker_title": "Interfaces en este equipo",
"kernel_iface_loading": "Cargando…",
- "kernel_iface_picker_help": "“Dispositivo” es opcional: un nombre de interfaz del kernel, o vacío para enlazar solo con la IP de escucha. Pulse una fila para rellenar."
+ "kernel_iface_picker_help": "“Dispositivo” es opcional: un nombre de interfaz del kernel, o vacío para enlazar solo con la IP de escucha. Pulse una fila para rellenar.",
+ "auto_iface_ifname_chips_hint": "Interfaces de este equipo: pulse para añadir o quitar nombres en el campo de arriba."
},
"map": {
"title": "Mapa",

diff --git a/meshchatx/src/frontend/locales/fr.json b/meshchatx/src/frontend/locales/fr.json
index 785a9e1a..8f50ea2b 100644
--- a/meshchatx/src/frontend/locales/fr.json
+++ b/meshchatx/src/frontend/locales/fr.json
@@ -908,7 +908,8 @@
"listen_ip_required": "L'adresse IP d'écoute est obligatoire.",
"kernel_iface_picker_title": "Interfaces sur cette machine",
"kernel_iface_loading": "Chargement…",
- "kernel_iface_picker_help": "Le champ Périphérique est optionnel : un seul nom d'interface noyau, ou laisser vide pour lier via l'IP d'écoute uniquement. Cliquez sur une ligne pour remplir."
+ "kernel_iface_picker_help": "Le champ Périphérique est optionnel : un seul nom d'interface noyau, ou laisser vide pour lier via l'IP d'écoute uniquement. Cliquez sur une ligne pour remplir.",
+ "auto_iface_ifname_chips_hint": "Interfaces sur cette machine : cliquez pour ajouter ou retirer des noms dans le champ ci-dessus."
},
"map": {
"title": "Carte",

diff --git a/meshchatx/src/frontend/locales/it.json b/meshchatx/src/frontend/locales/it.json
index 7223b741..8b877089 100644
--- a/meshchatx/src/frontend/locales/it.json
+++ b/meshchatx/src/frontend/locales/it.json
@@ -960,7 +960,8 @@
"listen_ip_required": "L'IP di ascolto è obbligatoria.",
"kernel_iface_picker_title": "Interfacce su questo host",
"kernel_iface_loading": "Caricamento…",
- "kernel_iface_picker_help": "Il dispositivo è facoltativo: un solo nome di interfaccia del kernel, o lascia vuoto e lega solo con l'IP di ascolto. Clic su una riga per compilare."
+ "kernel_iface_picker_help": "Il dispositivo è facoltativo: un solo nome di interfaccia del kernel, o lascia vuoto e lega solo con l'IP di ascolto. Clic su una riga per compilare.",
+ "auto_iface_ifname_chips_hint": "Interfacce su questo host: clic per aggiungere o rimuovere nomi nel campo sopra."
},
"map": {
"title": "Mappa",

diff --git a/meshchatx/src/frontend/locales/nl.json b/meshchatx/src/frontend/locales/nl.json
index 5ebe426b..790b728d 100644
--- a/meshchatx/src/frontend/locales/nl.json
+++ b/meshchatx/src/frontend/locales/nl.json
@@ -908,7 +908,8 @@
"listen_ip_required": "Listen-IP is verplicht.",
"kernel_iface_picker_title": "Interfaces op deze host",
"kernel_iface_loading": "Laden…",
- "kernel_iface_picker_help": "Apparaat is optioneel: één kernelinterfacenaam, of leeg laten en alleen via listen-IP binden. Klik op een regel om in te vullen."
+ "kernel_iface_picker_help": "Apparaat is optioneel: één kernelinterfacenaam, of leeg laten en alleen via listen-IP binden. Klik op een regel om in te vullen.",
+ "auto_iface_ifname_chips_hint": "Interfaces op deze host: klik om namen in het veld erboven toe te voegen of te verwijderen."
},
"map": {
"title": "Kaart",

diff --git a/meshchatx/src/frontend/locales/ru.json b/meshchatx/src/frontend/locales/ru.json
index 215743fb..2242d9d4 100644
--- a/meshchatx/src/frontend/locales/ru.json
+++ b/meshchatx/src/frontend/locales/ru.json
@@ -960,7 +960,8 @@
"listen_ip_required": "Укажите IP для прослушивания.",
"kernel_iface_picker_title": "Интерфейсы на этом узле",
"kernel_iface_loading": "Загрузка…",
- "kernel_iface_picker_help": "Поле «устройство» необязательно: одно имя интерфейса ядра или пусто — привязка только по Listen IP. Нажмите строку, чтобы подставить имя."
+ "kernel_iface_picker_help": "Поле «устройство» необязательно: одно имя интерфейса ядра или пусто — привязка только по Listen IP. Нажмите строку, чтобы подставить имя.",
+ "auto_iface_ifname_chips_hint": "Интерфейсы этого узла: нажмите, чтобы добавить или убрать имя в поле выше."
},
"map": {
"title": "Карта",

diff --git a/meshchatx/src/frontend/locales/zh.json b/meshchatx/src/frontend/locales/zh.json
index b1950a9c..57e744c9 100644
--- a/meshchatx/src/frontend/locales/zh.json
+++ b/meshchatx/src/frontend/locales/zh.json
@@ -908,7 +908,8 @@
"listen_ip_required": "Listen IP 为必填项。",
"kernel_iface_picker_title": "本机网络接口",
"kernel_iface_loading": "加载中…",
- "kernel_iface_picker_help": "“设备”为可选,填写一个内核网卡名,或留空仅按 Listen IP 绑定。点击一行填入输入框。"
+ "kernel_iface_picker_help": "“设备”为可选,填写一个内核网卡名,或留空仅按 Listen IP 绑定。点击一行填入输入框。",
+ "auto_iface_ifname_chips_hint": "本机接口:点击可在上方字段中添加或移除名称。"
},
"map": {
"title": "地图",


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────